package com.brainshare.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.brainshare.an.domain.AnWechatUser;
import com.brainshare.common.constant.NumberConstants;
import com.brainshare.common.enums.AnEntranceEnum;
import com.brainshare.common.enums.YNEnum;
import com.brainshare.common.utils.DateUtils;
import com.brainshare.common.utils.NumberUtils;
import com.brainshare.common.utils.StringUtils;
import com.brainshare.system.domain.RedPacketRecord;
import com.brainshare.system.domain.SysBuriedPoint;
import com.brainshare.system.domain.query.BuriedPointQuery;
import com.brainshare.system.domain.vo.StatisticsTrainCampTransformDetailVO;
import com.brainshare.system.domain.vo.StatisticsWithdrawalMoneyDetailVO;
import com.brainshare.system.mapper.RedPacketRecordMapper;
import com.brainshare.system.mapper.SysBuriedPointMapper;
import com.brainshare.system.service.IRedPacketRecordService;
import com.brainshare.utils.RedPacketResult;
import com.brainshare.utils.RedPacketUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * 红包记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-08-10
 */
@Service
public class RedPacketRecordServiceImpl implements IRedPacketRecordService 
{
    /**
     * 日志
     */
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RedPacketRecordMapper redPacketRecordMapper;

    @Autowired
    private SysBuriedPointMapper sysBuriedPointMapper;

    private final ReentrantLock lock = new ReentrantLock();


    /**
     * 查询红包记录
     * 
     * @param id 红包记录主键
     * @return 红包记录
     */
    @Override
    public RedPacketRecord selectRedPacketRecordById(Long id)
    {
        return redPacketRecordMapper.selectRedPacketRecordById(id);
    }

    @Override
    public String getWithdrawalMoneySum(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        Long withdrawalMoneySum = redPacketRecordMapper.getWithdrawalMoneySum(buriedPointQuery);
        String yuanValue = NumberUtils.getYuanValue(withdrawalMoneySum);
        return yuanValue;
    }

    @Override
    public List<StatisticsWithdrawalMoneyDetailVO> getWithdrawalMoneyDetailList(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        List<StatisticsWithdrawalMoneyDetailVO> withdrawalMoneyDetailList = redPacketRecordMapper.getWithdrawalMoneyDetailList(buriedPointQuery);
        return withdrawalMoneyDetailList;
    }

    public List<StatisticsWithdrawalMoneyDetailVO> getWithdrawalMoneyDetailList(List<StatisticsWithdrawalMoneyDetailVO> withdrawalMoneyDetailList) {
        if (CollectionUtils.isEmpty(withdrawalMoneyDetailList)){
            return null;
        }
        for (StatisticsWithdrawalMoneyDetailVO detailVO : withdrawalMoneyDetailList) {
            detailVO.setSnatchMoney(NumberUtils.getYuanValue(detailVO.getLongSnatchMoney()));
            detailVO.setWithdrawalMoney(NumberUtils.getYuanValue(detailVO.getLongWithdrawalMoney()));
        }
        return withdrawalMoneyDetailList;
    }

    @Override
    public Long getTrainCampTransferSum(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        Long trainCampTransferSum = redPacketRecordMapper.getTrainCampTransferSum(buriedPointQuery);
        return null== trainCampTransferSum? NumberConstants.ZERO:trainCampTransferSum;
    }

    @Override
    public List<StatisticsTrainCampTransformDetailVO> getTrainCampTransferDetailList(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        List<StatisticsTrainCampTransformDetailVO> trainCampTransferDetailList = redPacketRecordMapper.getTrainCampTransferDetailList(buriedPointQuery);
        return trainCampTransferDetailList;
    }

    @Override
    public List<StatisticsTrainCampTransformDetailVO> getTrainCampTransferDetailList(List<StatisticsTrainCampTransformDetailVO> trainCampTransferDetailList) {
        if (CollectionUtils.isEmpty(trainCampTransferDetailList)){
            return null;
        }

        long ts = DateUtils.getTimeMillis();
        List<Long> userIdList = trainCampTransferDetailList.stream().map(item -> item.getUserId()).collect(Collectors.toList());
        SysBuriedPoint sysBuriedPointParam = new SysBuriedPoint();
        sysBuriedPointParam.setCustomerIdList(userIdList);
        sysBuriedPointParam.setAnEntranceFlag(YNEnum.YES.getCode());
        List<SysBuriedPoint> allBuriedPointList = sysBuriedPointMapper.selectSysBuriedPointList(sysBuriedPointParam);
        for (StatisticsTrainCampTransformDetailVO detailVO : trainCampTransferDetailList) {
            if (null == detailVO || null == detailVO.getUserId()) {
                continue;
            }
            List<SysBuriedPoint>  buriedPointList = allBuriedPointList.stream().filter(item -> item.getCustomerId().equals(detailVO.getUserId())).collect(Collectors.toList());
            String anEntrance = StringUtils.EMPTY;
            if (!CollectionUtils.isEmpty(buriedPointList)) {
                SysBuriedPoint point = buriedPointList.stream().sorted(Comparator.comparing(SysBuriedPoint::getCreateDate).reversed()).findFirst().orElseGet(null);
                if (null == point || null == point.getSection() || null == point.getModule() || null == point.getFunction()) {
                    logger.info("ts:{} ，未找到筛查入口，或筛查入口字段值不正确", ts, point);
                } else {
                    anEntrance = AnEntranceEnum.getEntranceByPath(Integer.valueOf(point.getSection()), Integer.valueOf(point.getModule()), Integer.valueOf(point.getFunction()));
                }
            }
            detailVO.setAnEntrance(anEntrance);
        }


        return trainCampTransferDetailList;
    }


    /**
     * 查询红包记录列表
     * 
     * @param redPacketRecord 红包记录
     * @return 红包记录
     */
    @Override
    public List<RedPacketRecord> selectRedPacketRecordList(RedPacketRecord redPacketRecord)
    {
        return redPacketRecordMapper.selectRedPacketRecordList(redPacketRecord);
    }

    @Override
    public RedPacketRecord getRedPacketRecord(RedPacketRecord redPacketRecord) {
        return redPacketRecordMapper.getRedPacketRecord(redPacketRecord);
    }

    @Override
    public boolean sendRedPacketToUser(AnWechatUser anWechatUser, String orderId)
    {
        long ts = DateUtils.getTimeMillis();
        if (lock.tryLock())
        {
            try
            {
                RedPacketRecord query = new RedPacketRecord();
                query.setUserId(anWechatUser.getWechatUserId());
                query.setOrderNo(orderId);
                List<RedPacketRecord> lstRedPackRecord = selectRedPacketRecordList(query);
                if (lstRedPackRecord.size() == 0)
                {
                    logger.error("红包订单不存在 orderId" + orderId);
                    return false;
                }
                RedPacketRecord redPacketRecord = lstRedPackRecord.get(0);
                if (redPacketRecord.getRedPacketStatus() != 0)
                {
                    logger.error("不符合红包提现条件");
                    return false;
                }
                RedPacketResult redPacketResult = RedPacketUtils.sendRedPacket(orderId, redPacketRecord.getRedPacketAmount().toString(), anWechatUser.getOpenId());
                if (redPacketResult.getErrcode() == 0)
                {
                    redPacketRecord.setRedPacketStatus(1);
                    redPacketRecord.setOutTradeNo(redPacketResult.getTicket());
                    int result;
                    redPacketRecord.setOutTradeLog("提现接口响应参数" + JSON.toJSONString(redPacketResult));
                    result = redPacketRecordMapper.updateRedPacketRecord(redPacketRecord);
                    if (result > 0)
                    {
                        logger.info("红包提现成功！");
                        return true;
                    }
                } else
                {
                    redPacketRecord.setRedPacketStatus(2);
                    redPacketRecord.setOutTradeLog("提现接口响应参数" + JSON.toJSONString(redPacketResult));
                    redPacketRecordMapper.updateRedPacketRecord(redPacketRecord);
                }
                logger.info("红包提现失败！");
                return false;
            } catch (Exception e)
            {
                logger.error("ts:{}，发送红包异常", ts, e);
                return false;
            } finally
            {
                lock.unlock();
            }
        }
        return false;
    }

    /**
     * 新增红包记录
     * 
     * @param redPacketRecord 红包记录
     * @return 结果
     */
    @Override
    public int insertRedPacketRecord(RedPacketRecord redPacketRecord)
    {
        redPacketRecord.setCreateTime(DateUtils.getNowDate());
        redPacketRecordMapper.insertRedPacketRecord(redPacketRecord);
        Long id = redPacketRecord.getId();
        if (null==id){
            logger.warn("用户{}类型{}红包记录ID为空",redPacketRecord.getUserId(),redPacketRecord.getRedPacketType2());
        }
        return redPacketRecord.getId().intValue();
    }

    /**
     * 修改红包记录
     * 
     * @param redPacketRecord 红包记录
     * @return 结果
     */
    @Override
    public int updateRedPacketRecord(RedPacketRecord redPacketRecord)
    {
        redPacketRecord.setUpdateTime(DateUtils.getNowDate());
        return redPacketRecordMapper.updateRedPacketRecord(redPacketRecord);
    }

    /**
     * 批量删除红包记录
     * 
     * @param ids 需要删除的红包记录主键
     * @return 结果
     */
    @Override
    public int deleteRedPacketRecordByIds(Long[] ids)
    {
        return redPacketRecordMapper.deleteRedPacketRecordByIds(ids);
    }

    /**
     * 删除红包记录信息
     * 
     * @param id 红包记录主键
     * @return 结果
     */
    @Override
    public int deleteRedPacketRecordById(Long id)
    {
        return redPacketRecordMapper.deleteRedPacketRecordById(id);
    }

    @Override
    public int deleteRedPacketRecordByUserId(Long userId) {
        return redPacketRecordMapper.deleteRedPacketRecordByUserId(userId);
    }
}
